package com.github.llyb120.workflow.adapter;

import cn.hutool.core.util.StrUtil;
import com.github.llyb120.workflow.definition.Dealer;
import com.github.llyb120.workflow.domain.dos.*;
import lombok.Synchronized;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

public class MemoryDealer extends DealerAdapter{
    List<UserDo> userDos;
    List<RoleDo> roleDos;
    List<DepDo> depDos;
    List<UserRoleDo> userRoleDos;
    List<UserDepDo> userDepDos;

    Map<String, List<UserDo>> userMapByRole;// = new ConcurrentHashMap<>();
    Map<String, UserDo> userDoMap;

    @Synchronized
    public void init(List<UserDo> userDos, List<RoleDo> roleDos, List<DepDo> depDos, List<UserRoleDo> userRoleDos, List<UserDepDo> userDepDos) {
        this.userDos = new CopyOnWriteArrayList<>(userDos);
        this.roleDos = new CopyOnWriteArrayList<>(roleDos);
        this.depDos = new CopyOnWriteArrayList<>(depDos);
        this.userRoleDos = new CopyOnWriteArrayList<>(userRoleDos);
        this.userDepDos = new CopyOnWriteArrayList<>(userDepDos);


        //整理索引结构
        Map<String, UserDo> userDoMap = new ConcurrentHashMap<>();
        for (UserDo userDo : userDos) {
            userDoMap.put(userDo.getId(), userDo);
        }
        this.userDoMap = userDoMap;
        Map<String, List<UserDo>> userMapByRole = new ConcurrentHashMap<>();
        for (UserRoleDo userRoleDo : userRoleDos) {
            List<UserDo> list = userMapByRole.computeIfAbsent(userRoleDo.getRoleId(), k -> new CopyOnWriteArrayList<>());
            list.add(userDoMap.get(userRoleDo.getUserId()));
        }
        this.userMapByRole = userMapByRole;
    }

    @Override
    public List<UserDo> findDealers(List<Dealer> definition) {
        return definition.stream()
                .flatMap(e -> findSingleDealers(e).stream())
                .collect(Collectors.toList());
    }


    private List<UserDo> findSingleDealers(Dealer dealer){
        //角色查询
        List<UserDo> users = roleDos.stream().filter(e -> {
            //任意一个命中
            return Arrays.stream(dealer.getByRoleName()).anyMatch(ee -> StrUtil.equals(e.getName(), ee));
        }).flatMap(e -> {
            return userMapByRole.get(e.getId()).stream();
        }).collect(Collectors.toList());
        return users;
    }

}
